1 package org.apache.maven.surefire.common.junit4;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.report.ReportEntry;
23 import org.apache.maven.surefire.report.RunListener;
24 import org.apache.maven.surefire.report.SimpleReportEntry;
25 import org.apache.maven.surefire.report.StackTraceWriter;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.junit.runner.Description;
28 import org.junit.runner.Result;
29 import org.junit.runner.notification.Failure;
30
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue;
35 import static org.apache.maven.surefire.report.SimpleReportEntry.ignored;
36 import static org.apache.maven.surefire.report.SimpleReportEntry.withException;
37
38
39
40
41
42 public class JUnit4RunListener
43 extends org.junit.runner.notification.RunListener
44 {
45 private static final Pattern PARENS = Pattern.compile( "^" + ".+"
46 + "\\(("
47
48 + "[^\\\\(\\\\)]+"
49 + ")\\)" + "$" );
50
51 protected final RunListener reporter;
52
53
54
55
56
57 private final ThreadLocal<Boolean> failureFlag = new InheritableThreadLocal<Boolean>();
58
59
60
61
62
63
64 public JUnit4RunListener( RunListener reporter )
65 {
66 this.reporter = reporter;
67 }
68
69
70
71
72
73
74
75
76 public void testIgnored( Description description )
77 throws Exception
78 {
79 String reason = getAnnotatedIgnoreValue( description );
80 reporter.testSkipped( ignored( getClassName( description ), description.getDisplayName(), reason ) );
81 }
82
83
84
85
86
87
88 public void testStarted( Description description )
89 throws Exception
90 {
91 reporter.testStarting( createReportEntry( description ) );
92 failureFlag.remove();
93 }
94
95
96
97
98
99
100 @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" } )
101 public void testFailure( Failure failure )
102 throws Exception
103 {
104 String testHeader = failure.getTestHeader();
105 if ( isInsaneJunitNullString( testHeader ) )
106 {
107 testHeader = "Failure when constructing test";
108 }
109
110 ReportEntry report =
111 withException( getClassName( failure.getDescription() ), testHeader, createStackTraceWriter( failure ) );
112
113 if ( failure.getException() instanceof AssertionError )
114 {
115 reporter.testFailed( report );
116 }
117 else
118 {
119 reporter.testError( report );
120 }
121
122 failureFlag.set( true );
123 }
124
125 @SuppressWarnings( { "UnusedDeclaration" } )
126 public void testAssumptionFailure( Failure failure )
127 {
128 reporter.testAssumptionFailure( createReportEntry( failure.getDescription() ) );
129 failureFlag.set( true );
130 }
131
132
133
134
135
136
137 public void testFinished( Description description )
138 throws Exception
139 {
140 Boolean failure = failureFlag.get();
141 if ( failure == null )
142 {
143 reporter.testSucceeded( createReportEntry( description ) );
144 }
145 }
146
147
148
149
150 public void testExecutionSkippedByUser()
151 {
152 reporter.testExecutionSkippedByUser();
153 }
154
155 private static String getClassName( Description description )
156 {
157 String name = extractClassName( description );
158 if ( name == null || isInsaneJunitNullString( name ) )
159 {
160
161 Description subDescription = description.getChildren().get( 0 );
162 if ( subDescription != null )
163 {
164 name = extractClassName( subDescription );
165 }
166 if ( name == null )
167 {
168 name = "Test Instantiation Error";
169 }
170 }
171 return name;
172 }
173
174 protected StackTraceWriter createStackTraceWriter( Failure failure )
175 {
176 return new JUnit4StackTraceWriter( failure );
177 }
178
179 protected SimpleReportEntry createReportEntry( Description description )
180 {
181 return new SimpleReportEntry( getClassName( description ), description.getDisplayName() );
182 }
183
184 public static String extractClassName( Description description )
185 {
186 String displayName = description.getDisplayName();
187 Matcher m = PARENS.matcher( displayName );
188 return m.find() ? m.group( 1 ) : displayName;
189 }
190
191 public static String extractMethodName( Description description )
192 {
193 String displayName = description.getDisplayName();
194 int i = displayName.indexOf( "(" );
195 return i >= 0 ? displayName.substring( 0, i ) : displayName;
196 }
197
198 public static void rethrowAnyTestMechanismFailures( Result run )
199 throws TestSetFailedException
200 {
201 if ( run.getFailureCount() > 0 )
202 {
203 for ( Failure failure : run.getFailures() )
204 {
205 Description description = failure.getDescription();
206 if ( JUnit4ProviderUtil.isFailureInsideJUnitItself( description ) )
207 {
208 final Throwable exception = failure.getException();
209 throw new TestSetFailedException( exception );
210 }
211 }
212 }
213 }
214
215 private static boolean isInsaneJunitNullString( String value )
216 {
217 return "null".equals( value );
218 }
219 }